﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace SoftVenture.Sharepoint.Permissions
{
    public class ListHelper
    {
        SPWeb web;
        SPList list;

        public ListHelper(string url, string listName)
        {
            SPSecurity.RunWithElevatedPrivileges(
                delegate()
                {
                    using (SPSite elevatedSite = new SPSite(url))
                    {
                        this.web = elevatedSite.OpenWeb();
                    }
                }
            );

            this.list = web.Lists[listName];
        }

        public int List(bool showAll, ref string output)
        {

            if (showAll || this.list.HasUniqueRoleAssignments)
                foreach (SPRoleAssignment role in this.list.RoleAssignments)
                {
                    output += "\t" + role.Member.Name + Environment.NewLine;
                    foreach (SPRoleDefinition def in role.RoleDefinitionBindings)
                        if (showAll || !def.Hidden)
                            output += "\t\t" + def.Name + Environment.NewLine;
                }

            else
                output += "\tParent Inheritance" + Environment.NewLine;

            return 0;
        }

        public int BreakRoleInheritance(bool copyRoleAssigment, ref string output)
        {
            if (this.list.HasUniqueRoleAssignments)
            {
                output += string.Format("{0} already have unique roles. Nothing done.", this.list.Title);
                return 1;
            }

            output += string.Format("Breaking Parent Role Inheritance from list: {0}", this.list.Title);
            this.list.BreakRoleInheritance(copyRoleAssigment);
            this.list.Update();

            return 0;
        }

        public int ResetRoleInheritance(ref string output)
        {
            if (!this.list.HasUniqueRoleAssignments)
            {
                output += string.Format("{0} already have role inheritance. Nothing done.", this.list.Title);
                return 1;
            }

            output += string.Format("Reset Role Inheritance from list: {0}", this.list.Title);
            this.list.ResetRoleInheritance();
            this.list.Update();

            return 0;
        }

        public int Add(string roleName, string user, ref string output)
        {
            web.AllowUnsafeUpdates = true;

            SPRoleAssignment roleAssignment = BuildRoleAssignment(user);

            roleAssignment.RoleDefinitionBindings.Add(this.web.RoleDefinitions[roleName]);

            this.list.RoleAssignments.Add(roleAssignment);

            output += string.Format("Adding {0} to {1} in list {2}", roleName, user, this.list.Title); 
            
            web.Update();
            return 0;
        }

        public int Remove(string roleName, string user, ref string output)
        {
            web.AllowUnsafeUpdates = true;

            SPRoleAssignment roleAssignment = BuildRoleAssignment(user);

            foreach (SPRoleAssignment role in this.list.RoleAssignments)
            {
                if (role.Member.Name == user)
                {
                    roleAssignment.RoleDefinitionBindings.Add(this.web.RoleDefinitions[roleName]);
                    role.RoleDefinitionBindings.Remove(roleAssignment.RoleDefinitionBindings[0]);
                    role.Update();
                }
            }

            output += string.Format("Removing {0} to {1} in list {2}", roleName, user, this.list.Title); 

            web.Update();
            return 0;
        }

        public int RemoveAll(string user, ref string output)
        {
            web.AllowUnsafeUpdates = true;

            foreach (SPRoleAssignment role in this.list.RoleAssignments)
            {
                if (role.Member.Name == user)
                {
                    role.RoleDefinitionBindings.RemoveAll();
                    role.Update();
                }
            }

            output += string.Format("Removing all permissions to {0} in list {1}", user, this.list.Title); 

            web.Update();
            return 0;
        }

        private SPRoleAssignment BuildRoleAssignment(string user)
        {
            SPRoleAssignment roleAssignment = null;

            try
            {
                roleAssignment = new SPRoleAssignment(this.web.SiteGroups[user]);
            }
            catch (Exception)
            {
                roleAssignment =
                 new SPRoleAssignment(
                     user,
                     string.Empty,
                     string.Empty,
                     string.Empty);
            }

            return roleAssignment;
        }

        public void Dispose()
        {
            if (this.web != null)
            {
                this.web.Close();
                this.web.Dispose();
            }
        }
   }
}
